package com.tool.payment.service;

import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;

import com.tool.payment.PaymentConfig;
import com.tool.payment.exception.SDKRuntimeException;
import com.tool.payment.model.PayOrder;
import com.tool.payment.util.JsonUtils;

public class AbstractPaymentService {
	
	private static final Logger logger = org.slf4j.LoggerFactory.getLogger(AbstractPaymentService.class);
	
	@Autowired
	protected NotifyService notifyService;
	@Autowired
	protected PayOrderService payOrderService;
	

	protected String getUrl(HttpServletRequest request){
		String path = request.getRequestURL().toString();
		path = path.substring(0, path.indexOf("pay"));
		return path;
	}
	
	/**
	 * 修改支付订单
	 * @param payorderid
	 * @param status
	 * @param outtradeno
	 * @param isRetry
	 * @return
	 */
	protected PayOrder updatePayOrder(Object payorderid,int status,String outtradeno,boolean isRetry) {
		PayOrder payOrder = this.payOrderService.getPayOrderById(payorderid);
		if(payOrder == null) return null;
		if(!payOrder.getStatus().equals(PayOrder.STATUS_NO)) return null;
		PayOrder updatePayOrder = new PayOrder(payOrder.getId());
		updatePayOrder.setVersion(payOrder.getVersion());
		updatePayOrder.setUpdatetime(new Date());
		updatePayOrder.setStatus(status);
		updatePayOrder.setOuttradeno(outtradeno);
		try {
			this.payOrderService.updatePayOrder(updatePayOrder);
		} catch (Exception e) {
			logger.info("修改支付订单失败，payorder:" + JsonUtils.objToJson(payOrder),e);
			if(isRetry) {
				return this.updatePayOrder(payorderid, status, outtradeno, false);
			}
		}
		
		return payOrder;
	}
	
	/**
	 * 支付宝处理回调参数
	 * @param requestParams
	 * @param flag
	 * @return
	 */
	protected Map<String,String> getParams(Map requestParams,boolean flag){
		Map<String,String> params = new HashMap<String,String>();
		for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			if(!flag){
				try {
					//乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
					valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
				} catch (UnsupportedEncodingException e) {
					e.printStackTrace();
				}
			}
			params.put(name, valueStr);
		}
		return params;
	}
	
	/**
	 * 
	 * @author chriswu
	 * @todo 验证消息是否是微信发出的合法消息
	 * @params 通知返回来的参数数组
	 * @return 验证结果
	 */
    protected boolean weixinVerify(Map<String, String> params) {

       boolean resultVerify = true;
       
       //通信结果
       String return_code = params.get("return_code");
       
       if(return_code.equals("FAIL")){
    	   String return_msg = params.get("return_msg");
    	   logger.error("微信notify通信失败结果: " + return_msg);
    	   resultVerify= false;
       }
       
       //只有return_code为success的时候结构体里面的参数才会返回
       if(return_code.equals("SUCCESS")){
    	   
    	   //微信返回业务结果
    	   String result_code = params.get("result_code");
    	   
    	   if(result_code.equals("FAIL")){
        	   logger.error("微信notify业务失败结果: " + params.get("err_code_des"));
        	   resultVerify= false;
    	   }
    	   if(result_code.equals("SUCCESS")){
    		    String sign = "";
    		    if(params.get("sign") != null) {sign = params.get("sign");}
    		    resultVerify = getSignVeryfy(params, sign);
    	   }

       }
       
       return resultVerify;
    }
    
    
    
    /**
     * 
     * @author chriswu
     * @todo 根据反馈回来的信息，生成签名结果, 并与原签名比对
     * @params sign 比对的签名结果 ,  Params 通知返回来的参数数组
     */
	private boolean getSignVeryfy(Map<String, String> Params, String sign) {
		
		if(Params.get("sign")!=null){
			Params.remove("sign");
		}
        //获得签名验证结果
        boolean isSign = false;
        if(PaymentConfig.getInstance().getSignType().equals("MD5") ) {
        	
        	String mySign = "";
			try {
				mySign = PaymentConfig.getInstance().getSignStr(Params);
			} catch (SDKRuntimeException e) {
				logger.error("生成微信签名函数异常"+e.getMessage());
			}
        	isSign = mySign.equals(sign)?true:false;
        }
        return isSign;
    }
	
	protected Boolean handleWeiXinNotify(Map<String, String> parmap){
		
		boolean flag = false;
		String return_code = parmap.get("return_code");
		String result_code = parmap.get("result_code");
		
		if(return_code.equals("SUCCESS")){
			
			if(result_code.equals("SUCCESS")){
				flag = true;
			}else{
				flag = false;
				logger.info(parmap.get("err_code_des"));
			}
			
		}else{
			flag = false;
			logger.info(parmap.get("return_msg"));
		}
		
		return flag;
	}
}
